﻿﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WorldMapBase;
using WorldMapBase.Display;
using WorldMapBase.Tile;
using WorldMapBase.Tile.Pool;
using WorldMapNew;
using static WorldMapBase.WorldMapConfigData;

public class MapAlliancePointSystem : MonoBehaviour
{
    // ====================================== 缓存的配置和状态 ======================================

    Dictionary<int, bool> alliancePointState = new Dictionary<int, bool>(); // <mapIdx,bShow>
    Dictionary<int, int> alliancePointIds = new Dictionary<int, int>();// <mapIdx, allianceId> 街区点在120x120坐标下allianceId 方便判断相连

    // ====================================== 街区点道路相关 ======================================
    public class AlliancePointRoadInfo {
        public CommandTileElement roadObj;
        public int allianceId;
        public int rotation;
        public int chunckId;
        public int cfgLocalIdx;
        public Vector3 tileOffset;
        public Vector3 pointPos;
    }
    Dictionary<int, AlliancePointRoadInfo> alliancePointRoadInfos = new Dictionary<int, AlliancePointRoadInfo>(); // <mapIdx,roadInfo>
    Dictionary<int, CommandTileElement> alliancePointCross = new Dictionary<int, CommandTileElement>(); // <mapIdx * 10 + angleIdx,CommandTileElement>

    // ====================================== 其他 ======================================
    private IDisplayCommandInterface m_DisplayCommandInterface;
    public bool isEnable = true;

    public int _allianceChunckPointLineNum = 3; // 一个30x30 一行街区点数量 默认3个
    public int _alliancePointSize = 10;// 一个街区点所占尺寸 写死10
    public int _allianceTileLineNum = 0;// 大地图一行地图块数量
    public int _allianceMapPointLineNum = 120;// 大地图一行街区点数据
    public int _allainceTildHalfSize = 0;// 地图块尺寸0.5

    public int _nullRoadResId = 139;

    public List<int> tempUpdateIdx = new List<int>();

    // ====================================== 道路衔接 ======================================

    public const int roadConnectResId = 3;// 道路相接衔接资源id
    public int[] crossConnectResIds = new int[5] {-1, -1, 4, 5, 6}; // 道路路口衔接资源id
    Dictionary<int, CommandTileElement> allianceConnectRoad = new Dictionary<int, CommandTileElement>(); // <mapIdx * 10 + angleIdx ,CommandTileElement>
    public class AlliancePointCrossInfo
    {
        public CommandTileElement crossObj;
        public int type;
        public int angle;
    }
    Dictionary<int, AlliancePointCrossInfo> allianceCrossCross = new Dictionary<int, AlliancePointCrossInfo>(); // <mapIdx,AlliancePointCrossInfo>

    public void Init(IDisplayCommandInterface displayCommandInterface)
    {
        _allianceChunckPointLineNum = WorldEntry.m_iTileSize / _alliancePointSize;
        _allianceTileLineNum = WorldEntry.m_mapSize / WorldEntry.m_iTileSize;
        _allainceTildHalfSize = WorldEntry.m_iTileSize / 2;
        _allianceMapPointLineNum = WorldEntry.m_mapSize / _alliancePointSize;
        m_DisplayCommandInterface = displayCommandInterface;
    }

    public void DisPose()
    {
        isEnable = false;
        foreach (var road in alliancePointRoadInfos.Values)
        {
            if (road != null && road.roadObj != null)
            {
                ClassPoolManager.RecoverCommandTileEle(road.roadObj);
            }
        }
        alliancePointRoadInfos.Clear();
        foreach (var cross in alliancePointCross.Values)
        {
            if (cross != null)
            {
                ClassPoolManager.RecoverCommandTileEle(cross);
            }
        }
        alliancePointCross.Clear();
        foreach (var road in allianceConnectRoad.Values)
        {
            if (road != null)
            {
                ClassPoolManager.RecoverCommandTileEle(road);
            }
        }
        allianceConnectRoad.Clear();
        foreach (var cross in allianceCrossCross.Values)
        {
            if (cross != null && cross.crossObj != null)
            {
                ClassPoolManager.RecoverCommandTileEle(cross.crossObj);
            }
        }
        allianceCrossCross.Clear();
    }

    public void OnSystemEnable()
    {
        isEnable = true;
    }

    public void ResetAdorn()
    {
        foreach (var road in alliancePointRoadInfos.Values)
        {
            if (road != null && road.roadObj != null)
            {
                // WorldPoolManager.RecoverItem(road.roadObj);
                ClassPoolManager.RecoverCommandTileEle(road.roadObj);
                
            }
        }
        alliancePointRoadInfos.Clear();
        foreach (var cross in alliancePointCross.Values)
        {
            if (cross != null)
            {
                ClassPoolManager.RecoverCommandTileEle(cross);
            }
        }
        alliancePointCross.Clear();
        foreach (var road in allianceConnectRoad.Values)
        {
            if (road != null)
            {
                ClassPoolManager.RecoverCommandTileEle(road);
            }
        }
        allianceConnectRoad.Clear();
        foreach (var cross in allianceCrossCross.Values)
        {
            if (cross != null && cross.crossObj != null)
            {
                ClassPoolManager.RecoverCommandTileEle(cross.crossObj);
            }
        }
        allianceCrossCross.Clear();
    }

    // ============================================================ 更新 ============================================================ 

    public void UpdateAllinacePointDatas(string allianceDataStr, bool bInit)
    {
        if (string.IsNullOrEmpty(allianceDataStr)) return;
        tempUpdateIdx.Clear();
        string[] allianceDatas = allianceDataStr.Split("|");
        for (int i = 0; i < allianceDatas.Length; i++)
        {
            string allianceData = allianceDatas[i];
            string[] data = allianceData.Split(",");
            if (data.Length == 2)
            {
                int.TryParse(data[0], out int idx);
                int.TryParse(data[1], out int allianceId);

                bool oldState = false;
                alliancePointState.TryGetValue(idx, out oldState);
                int oldAllianceId = 0;
                alliancePointIds.TryGetValue(idx, out oldAllianceId);

                if (allianceId > 0)
                {
                    alliancePointState[idx] = true;
                    alliancePointIds[idx] = allianceId;
                }
                else
                {
                    alliancePointState[idx] = false;
                    alliancePointIds.Remove(idx);
                }
                if(!bInit)
                {
                    bool stateChange = (allianceId > 0) != oldState;
                    bool allianceIdChange = allianceId != oldAllianceId;
                    bool bDelete = GetAlliancePointIdxIsDelete(idx);
                    if ((stateChange || allianceIdChange) && !bDelete)
                    {
                        tempUpdateIdx.Add(idx);
                    }
                }
            }
        }

        for (int i = 0; i < tempUpdateIdx.Count; i++)
        {
            int mapIdx = tempUpdateIdx[i];
            bool state = alliancePointState[mapIdx];
            int allianceId = -1;
            alliancePointIds.TryGetValue(mapIdx, out allianceId);
            int tileIdx = GetTileIdxByMapIdx(mapIdx);
            // 判断该tileIdx 的块显示 调用更新
            int lod = DynamicLayerMgr.worldEntry.GetLODLevel();
            bool tileShow = TileDisplayManager.Instance.TileIsShowing(WorldEntry.PLANE_LAYER_ID, lod, tileIdx);
            if (tileShow)
            {
                UpdateAlliancePointState2(tileIdx, state, allianceId, mapIdx);
            }
        }
    }

    // 使用视野 点数据更新 -舍弃
    //public void UpdateAlliancePointState(int tileIdx, int posIdx, bool state, int allianceId, float point_x, float point_y)
    //{
    //    if (!isEnable) return;
    //    // 更新街区点表现
    //    int mapIdx = GetMapIdx(point_x, point_y);
    //    bool bChange = UpdateAlliancePointShow(tileIdx, state, allianceId, mapIdx);
    //    if (bChange)
    //    {
    //        // 更新出生点 衔接道路
    //        DynamicLayerMgr.worldEntry._mapPointAdornSystem.UpdateAdornRoad(tileIdx, mapIdx, state);
    //    }
    //}

    // 使用推送 联盟染色数据更新 
    public void UpdateAlliancePointState2(int tileIdx, bool state, int allianceId, int mapIdx)
    {
        if (!isEnable) return;
        // 更新街区点表现
        UpdateAlliancePointShow(tileIdx, state, allianceId, mapIdx);
        // 更新出生点 衔接道路
        DynamicLayerMgr.worldEntry._mapPointAdornSystem.UpdateAdornRoad(tileIdx, mapIdx, state);
    }

    public void UpdateAlliancePointShow(int tileIdx, bool state, int allianceId, int mapIdx)
    {
        int chunckId = GetChunckId(tileIdx, out int rotation);
        Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);
        int localIdx = GetLocalIdx3(tileIdx, mapIdx,rotation);
        // 更新街区点二车道
        UpdateAllianceRoad(mapIdx, chunckId, localIdx, rotation, tileOffset, state, allianceId);
        // 更新该街区点和其他街区点相连道路
        UpdateAllianceCrossShow(mapIdx, chunckId, localIdx, rotation, tileOffset, state);
        // 更新周围街区点表现
        UpdateAllianceOtherCrossShow(mapIdx, state);
        // 更新绿化衔接
        UpdateAllianceConnectShow(mapIdx);
        //Debug.LogFormat("[街区点道路] ============================================================= end");
    }

    // 更新mapIdx街区点二车道
    public void UpdateAllianceRoad(int mapIdx, int chunckId, int cfgLocalIdx, int rotation, Vector3 tileOffset, bool state,int allianceId)
    {
        if (state)
        {
            // 显示
            TileAlliancePointRoad roadData = GetRoad(chunckId, cfgLocalIdx);
            Vector3 localOffset = WorldMapConfigData.GetPosByAngle(roadData.position.x, 0, roadData.position.z, rotation);
            TilePointAdornData adornData = new TilePointAdornData(roadData);
            CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID, adornData,
                    tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);

            //// 设置位置等信息
            //obj.SetPosition(tileOffset + localOffset);
            //obj.SetRotation(new Vector3(0, rotation * 90, 0));
            //obj.SetScale(Vector3.one);
            // 记录
            AlliancePointRoadInfo info = new AlliancePointRoadInfo();
            info.roadObj = adornElement;
            info.allianceId = allianceId;
            info.rotation = rotation;
            info.chunckId = chunckId;
            info.cfgLocalIdx = cfgLocalIdx;
            info.tileOffset = tileOffset;
            alliancePointRoadInfos[mapIdx] = info;
        }
        else
        {
            // 删除
            if (alliancePointRoadInfos.ContainsKey(mapIdx))
            {
                AlliancePointRoadInfo roadInfo = alliancePointRoadInfos[mapIdx];
                ClassPoolManager.RecoverCommandTileEle(roadInfo.roadObj);
                alliancePointRoadInfos.Remove(mapIdx);
            }
            //alliancePointIds[mapIdx] = -1;
        }
    }

    // 更新mapIdx街区点的衔接道路
    public void UpdateAllianceCrossShow(int mapIdx, int chunckId, int cfgLocalIdx, int rotation, Vector3 tileOffset, bool state)
    {
        if (state)
        {
            int allianceId = alliancePointIds[mapIdx];
            if (allianceId <= 0) return;
            int mapIdx_x = mapIdx % _allianceMapPointLineNum;
            int mapIdx_y = mapIdx / _allianceMapPointLineNum;
            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    if (x * y == 0 && (x != 0 || y != 0)) // 排除原点 只取坐标轴 所以是上下左右
                    {
                        int mapIdx_x1 = mapIdx_x + x;
                        int mapIdx_y1 = mapIdx_y + y;
                        if (mapIdx_x1 < 0 || mapIdx_x1 >= _allianceMapPointLineNum || mapIdx_y1 < 0 || mapIdx_y1 >= _allianceMapPointLineNum) continue;
                        int mapIdx1 = mapIdx_x1 + mapIdx_y1 * _allianceMapPointLineNum;
                        int angleIdx1 = GetAngleIdx(x, y);
                        int crossKey = mapIdx * 10  + angleIdx1;

                        //Debug.LogFormat("[街区点道路] ================================== 检查自身衔接道路 mapIdx：{0} | angle {1}", mapIdx, angleIdx1);
                        int allianceId1 = -1;
                        if (!alliancePointIds.TryGetValue(mapIdx1, out allianceId1))
                        {
                            continue; // 不存在该点的联盟id
                        }

                        if (GetAlliancePointIdxIsDelete(mapIdx1)) continue;
                        if (allianceId == allianceId1)
                        {
                            // 新增
                            //Debug.LogFormat("[街区点道路] ================================== 新增 自身衔接道路 mapIdx：{0} | angle {1}", mapIdx, angleIdx1);
                            Vector3 v0 = GetPosByAngle2(x, 0, y, rotation);
                            int angleIdx0 = GetAngleIdx((int)v0.x, (int)v0.z);
                            TileAlliancePointCross cross = GetCross(chunckId, cfgLocalIdx, angleIdx0);
                            Vector3 localOffset = WorldMapConfigData.GetPosByAngle(cross.position.x, 0, cross.position.z, rotation);
                            TilePointAdornData adornData = new TilePointAdornData(cross);
                            CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_CROSS_LAYER_ID, adornData,
                                tileOffset + localOffset, false, rotation, m_DisplayCommandInterface);
                            // 记录
                            if (alliancePointCross.ContainsKey(crossKey))
                            {
                                ClassPoolManager.RecoverCommandTileEle(alliancePointCross[crossKey]);
                                alliancePointCross.Remove(crossKey);
                            }
                            alliancePointCross[crossKey] = adornElement;
                        }
                        else
                        {
                            // 删除
                            if (alliancePointCross.ContainsKey(crossKey))
                            {
                                ClassPoolManager.RecoverCommandTileEle(alliancePointCross[crossKey]);
                                alliancePointCross.Remove(crossKey);
                                //alliancePointCross[crossKey] = null;
                            }
                        }
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i <= 3; i++)
            {
                int crossKey = mapIdx * 10 + i;
                //Debug.LogFormat("[街区点道路] ================================== 删除自身衔接道路 mapIdx：{0} | angle {1}", mapIdx, i);
                if (alliancePointCross.ContainsKey(crossKey))
                {
                    //Debug.LogFormat("[街区点道路] ================================== 删除自身衔接道路 成功 mapIdx：{0} | angle {1}", mapIdx, i);
                    ClassPoolManager.RecoverCommandTileEle(alliancePointCross[crossKey]);
                    alliancePointCross.Remove(crossKey);
                    //alliancePointCross[crossKey] = null;
                }
            }
    
        }
    }

    // 更新mapIdx周围街区点的衔接道路
    public void UpdateAllianceOtherCrossShow(int mapIdx, bool state)
    {
        int allianceId = -1;
        if (alliancePointIds.ContainsKey(mapIdx))
        {
            allianceId = alliancePointIds[mapIdx];
        }
        int mapIdx_x = mapIdx % _allianceMapPointLineNum;
        int mapIdx_y = mapIdx / _allianceMapPointLineNum;
        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                if (x * y == 0 && (x != 0 || y != 0)) // 排除原点 只取坐标轴 所以是上下左右
                {
                    int mapIdx_x1 = mapIdx_x + x;
                    int mapIdx_y1 = mapIdx_y + y;
                    if (mapIdx_x1 < 0 || mapIdx_x1 >= _allianceMapPointLineNum || mapIdx_y1 < 0 || mapIdx_y1 >= _allianceMapPointLineNum) continue;
                    int mapIdx1 = mapIdx_x1 + mapIdx_y1 * _allianceMapPointLineNum;
                    int allianceId1 = 0;
                    if (!alliancePointIds.TryGetValue(mapIdx1, out allianceId1))
                    {
                        //continue; // 不存在该点的联盟id
                    }
                    int angleIdx1 = GetAngleIdx(x, y);
                    angleIdx1 = (angleIdx1 + 2) % 4;
                    int crossKey = mapIdx1 * 10 + angleIdx1;

                    if (allianceId == allianceId1 && allianceId1 > 0 && alliancePointRoadInfos.ContainsKey(mapIdx1)) // 这里要注意 有可能有状态 有联盟id 但是没roadInfo
                    {
                        // 新增
                        AlliancePointRoadInfo roadInfo = alliancePointRoadInfos[mapIdx1];
                        Vector2Int vec = GetAnglePos(angleIdx1);
                        Vector3 v0 = GetPosByAngle2(vec.x, 0, vec.y, roadInfo.rotation);
                        int angleIdx0 = GetAngleIdx((int)v0.x, (int)v0.z);
                        TileAlliancePointCross cross = GetCross(roadInfo.chunckId, roadInfo.cfgLocalIdx, angleIdx0);
                        Vector3 tileOffset = roadInfo.tileOffset;
                        Vector3 localOffset = WorldMapConfigData.GetPosByAngle(cross.position.x, 0, cross.position.z, roadInfo.rotation);
                        TilePointAdornData adornData = new TilePointAdornData(cross);
                        CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_CROSS_LAYER_ID, adornData,
                            tileOffset + localOffset, false, roadInfo.rotation, m_DisplayCommandInterface);
                        // 记录
                        if (alliancePointCross.ContainsKey(crossKey))
                        {
                            ClassPoolManager.RecoverCommandTileEle(alliancePointCross[crossKey]);
                            alliancePointCross.Remove(crossKey);
                            //alliancePointCross[crossKey] = null;
                        }
                        alliancePointCross[crossKey] = adornElement;
                    }
                    else
                    {
                        // 直接删除
                        if (alliancePointCross.ContainsKey(crossKey))
                        {
                            ClassPoolManager.RecoverCommandTileEle(alliancePointCross[crossKey]);
                            alliancePointCross.Remove(crossKey);
                            //alliancePointCross[crossKey] = null;
                        }
                    }
                }
            }
        }
    }

    public bool[] tempConnetStates = new bool[4] {false,false,false,false};
    // 更新mapIdx周围衔接
    public void UpdateAllianceConnectShow(int mapIdx)
    {
        // 更新道路衔接不需要判断alllianceId
        int mapIdx_x = mapIdx % _allianceMapPointLineNum;
        int mapIdx_y = mapIdx / _allianceMapPointLineNum;
        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                int mapIdx_x1 = mapIdx_x + x;
                int mapIdx_y1 = mapIdx_y + y;
                if (mapIdx_x1 < 0 || mapIdx_x1 >= _allianceMapPointLineNum || mapIdx_y1 < 0 || mapIdx_y1 >= _allianceMapPointLineNum) continue;
                int mapIdx1 = mapIdx_x1 + mapIdx_y1 * _allianceMapPointLineNum;
                if (x * y == 0 && (x + y >= 0)) 
                {
                    // 更新道路连接
                    // ======================================================================================================================== 
                    // 每个mapIdx只记录左侧 和 下侧的道路衔接 在地图边缘的不显示
                    //|           
                    //| mapIdx1    
                    //| __ __      
                    // 所以当一个mapIdx的道路发送改变 只需要更新以下三个idx保存的道路衔接 就可以更新mapIdx周围4面的衔接道路
                    //|
                    //| mapIdx1
                    //| __ __
                    //|        |
                    //| mapIdx | mapIdx2
                    //| __ __  | __ __
                    // ======================================================================================================================== 
                    // 下侧
                    if (mapIdx_y1 > 0)
                    {
            
                        int mapIdx2 = mapIdx_x1 + (mapIdx_y1 - 1) * _allianceMapPointLineNum;
                        int roadKey = mapIdx1 * 10 + 2;
                        bool bShow = false;
                        bool bConnect = alliancePointRoadInfos.ContainsKey(mapIdx1) && alliancePointRoadInfos.ContainsKey(mapIdx2);
                        if (bConnect)
                        {
                            AlliancePointRoadInfo info1 = alliancePointRoadInfos[mapIdx1];
                            AlliancePointRoadInfo info2 = alliancePointRoadInfos[mapIdx2];
                            bShow = info1.roadObj.GetResId() != _nullRoadResId && info2.roadObj.GetResId() != _nullRoadResId;
                        }
                        if (bShow)
                        {
                            if (!allianceConnectRoad.ContainsKey(roadKey))
                            {
                                float pos_x = (mapIdx_x1 + 0.5f) * _alliancePointSize;
                                float pos_z = mapIdx_y1 * _alliancePointSize;
                                //obj.SetPosition(new Vector3(pos_x,0, pos_z));
                                //obj.SetRotation(Vector3.zero);
                                //obj.SetScale(Vector3.one);
                                //obj.GetRefTrans.gameObject.name = roadKey.ToString();
                                TilePointAdornData adornData = new TilePointAdornData(roadConnectResId);
                                CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID, adornData,
                                    new Vector3(pos_x, 0, pos_z), false, 0, m_DisplayCommandInterface);

                                allianceConnectRoad[roadKey] = adornElement;
                            }
                        }
                        else
                        {
                            if (allianceConnectRoad.ContainsKey(roadKey))
                            {
                                CommandTileElement obj = allianceConnectRoad[roadKey];
                                ClassPoolManager.RecoverCommandTileEle(obj);
                                allianceConnectRoad.Remove(roadKey);
                                //allianceConnectRoad[roadKey] = null;
                            }
                        }
                    }
                    // 左侧
                    if (mapIdx_x1 > 0)
                    {
                        int mapIdx2 = (mapIdx_x1 - 1) + mapIdx_y1 * _allianceMapPointLineNum;
                        int roadKey = mapIdx1 * 10 + 3;
                        bool bShow = false;
                        bool bConnect = alliancePointRoadInfos.ContainsKey(mapIdx1) && alliancePointRoadInfos.ContainsKey(mapIdx2);
                        if (bConnect)
                        {
                            AlliancePointRoadInfo info1 = alliancePointRoadInfos[mapIdx1];
                            AlliancePointRoadInfo info2 = alliancePointRoadInfos[mapIdx2];
                            bShow = info1.roadObj.GetResId() != _nullRoadResId && info2.roadObj.GetResId() != _nullRoadResId;
                        }
                        if (bShow)
                        {
                            if (!allianceConnectRoad.ContainsKey(roadKey))
                            {
                                float pos_x = mapIdx_x1 * _alliancePointSize;
                                float pos_z = (mapIdx_y1 + 0.5f) * _alliancePointSize;
                                //obj.SetPosition(new Vector3(pos_x, 0, pos_z));
                                //obj.SetRotation(Vector3.up * 90);
                                //obj.SetScale(Vector3.one);
                                //obj.GetRefTrans.gameObject.name = roadKey.ToString();
                                TilePointAdornData adornData = new TilePointAdornData(roadConnectResId);
                                CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID, adornData,
                                    new Vector3(pos_x, 0, pos_z), false, 0, m_DisplayCommandInterface);
                                allianceConnectRoad[roadKey] = adornElement;
                            }
                        }
                        else
                        {
                            if (allianceConnectRoad.ContainsKey(roadKey))
                            {
                                CommandTileElement obj = allianceConnectRoad[roadKey];
                                ClassPoolManager.RecoverCommandTileEle(obj);
                                allianceConnectRoad.Remove(roadKey);
                                //allianceConnectRoad[roadKey] = null;
                            }
                        }
                    }
                }
                if (x >= 0 && y >= 0)
                {
                    // 更新路口连接
                    // ======================================================================================================================== 
                    // 每个mapIdx只记录左下角路口衔接 在地图边缘的不显示
                    //           
                    //  mapIdx1    
                    // O     
                    // 所以当一个mapIdx的道路发送改变 只需要更新以下四个idx保存的路口衔接 就可以更新mapIdx周围4点的路口
                    //
                    //  mapIdx1  mapIdx2
                    // O       O
                    //  mapIdx   mapIdx3
                    // O       O 
                    // ======================================================================================================================== 
                    if (mapIdx_x1 > 0 && mapIdx_y1 > 0)
                    {
                        // 获得该路口相交的街区点状态
                        AlliancePointRoadInfo lt = GetRoadInfo(mapIdx_x1 - 1, mapIdx_y1,true);
                        AlliancePointRoadInfo rt = GetRoadInfo(mapIdx_x1, mapIdx_y1, true);
                        AlliancePointRoadInfo rb = GetRoadInfo(mapIdx_x1, mapIdx_y1 - 1, true);
                        AlliancePointRoadInfo lb = GetRoadInfo(mapIdx_x1 - 1, mapIdx_y1 - 1, true);
                        tempConnetStates[0] = lt != null;
                        tempConnetStates[1] = rt != null;
                        tempConnetStates[2] = rb != null;
                        tempConnetStates[3] = lb != null;
                        int crossType = 0; // 路口类型 注：预制体要按照左上为缺口 为默认方向
                        int crossAngle = -1;// 路口方向
                        int otherCrossAngle = -1;// 路口方向2 用于判断两路口情况下 缺口连续
                        for (int i = 0; i < tempConnetStates.Length; i++)
                        {
                            bool connect = tempConnetStates[i];
                            if (connect)
                            {
                                crossType += 1;
                            }
                            if (!connect && crossAngle < 0)
                            {
                                crossAngle = i;
                            }
                            else if (!connect && otherCrossAngle < 0)
                            {
                                otherCrossAngle = i;
                            }
                        }
                        if (crossType == 2) // 两个路口相连要检查一下 要是连续的
                        {
                            int disCrossAngle = Mathf.Abs(crossAngle - otherCrossAngle);
                            if (disCrossAngle == 2)
                            {
                                crossType = 1;// 两个缺口方向不是相连的 代表记录的crossType也不是相连的
                            }
                            else if (disCrossAngle == 3)
                            {
                                crossAngle = otherCrossAngle;
                            }
                            
                        }

                        if (crossType > 1) // 路口起码得是相连的两个
                        {
                            if (allianceCrossCross.ContainsKey(mapIdx1))
                            {
                                // 存在旧路口 判断类型不一致的时候更新
                                AlliancePointCrossInfo oldCross = allianceCrossCross[mapIdx1];
                                if (oldCross.angle != crossAngle || oldCross.type != crossType)
                                {
                                    ClassPoolManager.RecoverCommandTileEle(oldCross.crossObj);
                                    //allianceCrossCross[mapIdx1] = null;
                                    allianceCrossCross.Remove(mapIdx1);
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            // 新增
                            int resId = crossConnectResIds[crossType];
                            float pos_x = mapIdx_x1 * _alliancePointSize;
                            float pos_z = mapIdx_y1 * _alliancePointSize;
                            //obj.SetPosition(new Vector3(pos_x, 0, pos_z));
                            //obj.SetRotation(Vector3.up * crossAngle * 90);
                            //obj.SetScale(Vector3.one);

                            TilePointAdornData adornData = new TilePointAdornData(resId);
                            CommandTileElement adornElement = CommandTileElement.Create(WorldEntry.ALLIANCEPOINT_ROAD_LAYER_ID, adornData,
                                new Vector3(pos_x, 0, pos_z), false, crossAngle, m_DisplayCommandInterface);

                            AlliancePointCrossInfo cross = new AlliancePointCrossInfo();
                            cross.type = crossType;
                            cross.angle = crossAngle;
                            cross.crossObj = adornElement;
                            allianceCrossCross[mapIdx1] = cross;
                        }
                        else
                        {
                            if (allianceCrossCross.ContainsKey(mapIdx1))
                            {
                                AlliancePointCrossInfo cross = allianceCrossCross[mapIdx1];
                                ClassPoolManager.RecoverCommandTileEle(cross.crossObj);
                                //allianceCrossCross[mapIdx1] = null;
                                allianceCrossCross.Remove(mapIdx1);
                            }
                        }
                    }
                }
            }
        }
    }

    // ============================================================ 地块更新 ============================================================ 

    // 地图块新增和删除的时候调用
    public void UpdateTileAlliancePoint(int tileIdx,bool bShow)
    {
        //var watch = new System.Diagnostics.Stopwatch();
        //watch.Start();
        if (!isEnable) return;
        // 更新tileIdx 的九个10x10区域的联盟街区点表现
        Vector2Int center = GetTileCenterMapIdxs(tileIdx);
        int chunckId = GetChunckId(tileIdx, out int rotation);
        for (int x = -1; x <= 1; x++)
        {
            for (int y = -1; y <= 1; y++)
            {
                int mapIdx_x = center.x + x;
                int mapIdx_y = center.y + y;
                int mapIdx = mapIdx_x + mapIdx_y * _allianceMapPointLineNum;
                if (GetAlliancePointIdxIsDelete(mapIdx)) continue;
                alliancePointState.TryGetValue(mapIdx, out bool state);
                state = state && bShow;
                alliancePointIds.TryGetValue(mapIdx, out int allianceId);
                int localIdx = GetLocalIdx2(x, y, rotation);
                Vector3 tileOffset = WorldMapConfigData.GetTileOffset(tileIdx);
                // 更新街区点二车道
                UpdateAllianceRoad(mapIdx, chunckId, localIdx, rotation, tileOffset, state, allianceId);
                // 更新该街区点和其他街区点相连道路
                UpdateAllianceCrossShow(mapIdx, chunckId, localIdx, rotation, tileOffset, state);
                // 更新绿化衔接
                UpdateAllianceConnectShow(mapIdx);
            }
        }
        //watch.Stop();
        //Debug.LogError("[街区点滑动测试] ====================================== time : " + watch.Elapsed.TotalMilliseconds);
    }

    // ============================================================ 删除 ============================================================ 

    // 移除一个地图块的街区点表现
    public void RemvoeAlliancePointAdorn(int tileIdx)
    {
        if (!isEnable) return;
        int tileIdx_x = tileIdx % _allianceTileLineNum;
        int tileIdx_y = tileIdx / _allianceTileLineNum;

    }

    // ============================================================ 其他 ============================================================ 

    // 获得街区点在30x30中一维下标
    public int GetLocalIdx(int point_x, int point_y,int rotation)
    {
        int localIdx = -1;
        point_x = point_x % WorldEntry.m_iTileSize;
        point_y = point_y % WorldEntry.m_iTileSize;

        Vector3 v30 = GetPosByAngle2(point_x - 15, 0, point_y - 15, rotation); // 要代入相对位置旋转

        Vector3 local_v3 = new Vector3(v30.x + 15, 0, v30.z + 15);
        int idx_x = (int)(local_v3.x / _alliancePointSize);
        int idx_y = (int)(local_v3.z / _alliancePointSize);
        localIdx = idx_x + idx_y * _allianceChunckPointLineNum;
        return localIdx;
    }

    // 获得街区点在120x120中一维下标
    public int GetMapIdx(float point_x, float point_y)
    {
        int mapIdx = -1;
        int point_x0 = (int)(point_x / _alliancePointSize);
        int point_y0 = (int)(point_y / _alliancePointSize);
        mapIdx = point_x0 + point_y0 * _allianceMapPointLineNum;
        return mapIdx;
    }

    public Vector3 GetMapPos(int mapIdx)
    {
        Vector3 pos = Vector3.zero;
        int point_x = (int)(mapIdx % _allianceMapPointLineNum);
        int point_y = (int)(mapIdx / _allianceMapPointLineNum);
        pos.x = (point_x + 0.5f) * _alliancePointSize;
        pos.z = (point_y + 0.5f) * _alliancePointSize;
        return pos;
    }

    public int GetAngleIdx(int x, int y)
    {
        int angleIdx = 0;
        if (x == 0)
        {
            if (y > 0)
            {
                angleIdx = 0;
            }
            else
            {
                angleIdx = 2;
            }
        }
        else
        {
            if (x > 0)
            {
                angleIdx = 1;
            }
            else
            {
                angleIdx = 3;
            }
        }
        return angleIdx;
    }

    public Vector2Int GetAnglePos(int idx)
    {
        Vector2Int vec = new Vector2Int(0, 0);
        if (idx == 0)
        {
            vec.x = 0;
            vec.y = 1;
        }
        else if (idx == 2)
        {
            vec.x = 0;
            vec.y = -1;
        }
        else if (idx == 1)
        {
            vec.x = 1;
            vec.y = 0;
        }
        else if (idx == 3)
        {
            vec.x = -1;
            vec.y = 0;
        }
        return vec;
    }

    /// <summary>
    /// 获取本地缓存道路数据
    /// </summary>
    /// <param name="mapIdx_x"></param>
    /// <param name="mapIdx_y"></param>
    /// <param name="checkResId">是否检测资源id正确 如果是空道路资源点 是不需要相连的</param>
    /// <returns></returns>
    public AlliancePointRoadInfo GetRoadInfo(int mapIdx_x,int mapIdx_y,bool checkResId = false)
    {
        AlliancePointRoadInfo info = null;
        if (mapIdx_x < 0 || mapIdx_x >= _allianceMapPointLineNum || mapIdx_y < 0 || mapIdx_y >= _allianceMapPointLineNum) return info;
        int mapIdx = mapIdx_x + mapIdx_y * _allianceMapPointLineNum;
        alliancePointRoadInfos.TryGetValue(mapIdx, out info);
        if (checkResId && info != null && (info.roadObj == null || info.roadObj.GetResId() == _nullRoadResId)) 
        {
            return null;
        }
        return info;
    }

    public Vector3 GetTileOffset(int tileIdx)
    {
        Vector3 offset = Vector3.zero;
        int tile_x = tileIdx % _allianceTileLineNum;
        int tile_y = tileIdx / _allianceTileLineNum;
        offset.x = (tile_x + 1) * _allainceTildHalfSize;
        offset.z = (tile_y + 1) * _allainceTildHalfSize;
        return offset;
    }

    public bool GetRoadShowByIdx(int mapIdx_x,int mapIdx_y)
    {
        bool res = false;
        if (mapIdx_x < 0 || mapIdx_x >= _allianceMapPointLineNum || mapIdx_y < 0 || mapIdx_y >= _allianceMapPointLineNum) return res;
        int mapIdx = mapIdx_x + mapIdx_y * _allianceMapPointLineNum;
        res = alliancePointRoadInfos.ContainsKey(mapIdx);
        return res;
    }

    public bool GetAlliancePointShow(int mapIdx)
    {
        bool bShow = false;
        alliancePointState.TryGetValue(mapIdx, out bShow);
        if (GetAlliancePointIdxIsDelete(mapIdx)) bShow = false; 
        return bShow;
    }

    public Vector2Int GetTileCenterMapIdxs(int tileIdx)
    {
        Vector2Int center = Vector2Int.zero;
        int tileIdx_x = tileIdx % _allianceTileLineNum;
        int tileIdx_y = tileIdx / _allianceTileLineNum;
        center.x = tileIdx_x * _allianceChunckPointLineNum + 1;
        center.y = tileIdx_y * _allianceChunckPointLineNum + 1;
        return center;
    }

    // 通过本地坐标获得一维idx
    public int GetLocalIdx2(int local_x, int local_y, int rotation)
    {
        int idx = 0;
        Vector3 v3 = GetPosByAngle2(local_x, 0, local_y, rotation); // 要代入相对位置旋转
        v3 = v3 + Vector3.one; // 将相对中心坐标 转换为 相对左下角坐标
        idx = (int)v3.x + (int)v3.z * _allianceChunckPointLineNum;
        return idx;
    }

    public int GetTileIdxByMapIdx(int mapIdx)
    {
        int tileIdx = -1;
        int mapIdx_x = mapIdx % _allianceMapPointLineNum;
        int mapIdx_y = mapIdx / _allianceMapPointLineNum;
        int tileIdx_x = mapIdx_x / _allianceChunckPointLineNum;
        int tileIdx_y = mapIdx_y / _allianceChunckPointLineNum;
        tileIdx = tileIdx_x + tileIdx_y * _allianceTileLineNum;
        return tileIdx;
    }

    public int GetLocalIdx3(int tileIdx, int mapIdx, int rotation)
    {
        int localIdx = 0;
        Vector2Int center = GetTileCenterMapIdxs(tileIdx);
        int mapIdx_x = mapIdx % _allianceMapPointLineNum;
        int mapIdx_y = mapIdx / _allianceMapPointLineNum;
        localIdx = GetLocalIdx2(mapIdx_x - center.x, mapIdx_y - center.y, rotation);
        return localIdx;
    }
}